<template>
	<view class="dragsort-box">
		<movable-area id="drag" class="dragsort-area">
			<view id="dragsort-before" class="dragsort-before">
				<slot name="before"></slot>
			</view>
			<view id="dragsort-list" class="dragsort-list" :style="{'height':listHeight+'px'}"></view>
			<movable-view v-for="(item, index) in list" :key="index" :x="item.x" :y="item.y" :data-id="item.id" :data-sortid="item.sortID" :data-isadd="item.isAdd"
			 @touchstart="touchstart" @touchmove.stop="touchmove" @touchend="touchend" :direction="item.direction" damping="40" :animation="item.animation" :disabled="item.disabled" 
			 class="dragsort-view" :class="{'dragsort-view-active': isDrag&&activeModel&&activeModel.id == item.id}" :style="{
				 'width':item.width+'px',
				 'height':item.height+'px'
			 }">
				<view v-if="!item.isAdd" class="dragsort-view-item" @click.stop="onClick(item,index,list)">
					<u-image width="100%" height="100%" :src="fixResourcesUrl(item.src)"></u-image>
				</view>
				<view v-if="item.isAdd" class="dragsort-view-item" @click.stop="onAdd">
					<view class="btnAdd">
						<u-icon class="btnAdd-icon" name="plus" color="#B2B2B2" size="90"></u-icon>
					</view>
				</view>
			</movable-view>
			<view id="dragsort-after" class="dragsort-after">
				<slot name="after"></slot>
			</view>
			<view id="dragsort-delete" class="dragsort-delete" :class="isDrag?'opacity':''">
				<u-icon class="deleteicon" name="trash" color="#FFFFFF" size="34"></u-icon>
				<view>{{deleteText}}</view>
			</view>
		</movable-area>
	</view>
</template>

<script>
	let timeOut = 0;
	let debounceWait = 300;
	let touchTimeOut = 0;
	let touchDebounceWait = 300;
	let touchMoveTimeOut = 0;
	let touchMoveDebounceWait = 10;
	let lastTouchE = null;
	export default {
		name: 'drag-sort',
		mixins: [],
		components: {},
		data() {
			return {
				list: [], // 外部传入集合总数
				row: 0, // 总行数，根据集合总数和列数进行计算
				width:0, // Item元素宽度，根据列数进行计算
				height: 0, // Item元素高度，同宽度
				windowWidth: 0, // 屏幕宽度
				listHeight: 0, // 拖拽元素列表的高度【主要是用于撑起拖拽区域dragsort-list】
				beforeHeight: 0, // before区域高度
				afterHeight: 0, // after区域高度
				topY: 0, // 容器距离设备顶部的距离
				topX: 0, // 容器距离设备左侧偏移位置
				activeModel: null, // 当前激活的元素
				activeX: 0, //激活元素旧的x偏移
				activeY: 0, //激活元素旧的y偏移
				targetModel: null,// 当前目标元素
				targetX: 0, // 记录的旧的目标元素x偏移
				targetY: 0, // 记录的旧的目标元素y偏移
				isDrag: false, // 标记是否为拖动触发
				deleteArea:null, // 删除区域信息
				deleteText:'拖动到此处删除',
				modelCount: 0, // 记录元素个数，排除新增按钮元素
				maxSortID:0, // 当前数组中最大的排序号
				addObject:null, // 新增按钮实体元素
				isUpdate:false, // 数据是否需要更新，如果没有找到目标元素，那么此值始终是false，用于判断是否需要触发update更新事件
			}
		},
		computed: { },
		props: {
			value: {
				type: Array,
				default: () => {
					return []
				}
			},
			// 默认3列
			column: {
				type: Number,
				default: () => {
					return 3
				}
			},
			// 元素最多数量
			maxCount: {
				type: Number,
				default: () => {
					return 9
				}
			},
			// 容器左右内间隔【同padding】,单位px
			areaXGap: {
				type: Number,
				default: () => {
					return 15
				}
			},
			// 容器上下内间隔【同padding】,单位px
			areaYGap: {
				type: Number,
				default: () => {
					return 10
				}
			},
			// 元素的间距【元素和元素之间的间隔】,单位px
			viewGap: {
				type: Number,
				default: () => {
					return 4
				}
			},
		},
		watch: {
			value: {
				handler() {
					// console.info(this.value);
					this.reset();
					this.init();
					this.initGrid();
				},
				deep: true
			}
		},
		created() {
			const res = uni.getSystemInfoSync();
			this.windowWidth = res.windowWidth
		},
		mounted() {
			this.$nextTick(function() {
				var query = uni.createSelectorQuery().in(this)
				query.select('#dragsort-before').boundingClientRect()
				query.select('#dragsort-after').boundingClientRect()
				query.exec((res) => {
					this.beforeHeight = res[0].height;
					this.afterHeight = res[1].height;
					
					this.init();
					this.initGrid();
				});
			})
		},
		updated() {},
		filters: {},
		methods: {
			reset(){
				this.addObject = null;
			},
			// 对传入的集合进行初始化处理，根据排序号进行排序操作，后续内部处理不会改变集合的元素索引排序
			init(){
				var arr = [];
				if(this.value && this.value.length>0){
					arr.push(...this.value);
				}
				
				// 先根据排序编号进行排序,序号越小越靠前
				arr.sort(function(a,b){
					return a.sortID - b.sortID;
				})
				// 只取前this.maxCount个元素，不能多于this.maxCount个元素
				// console.info(arr);
				// console.info(arr.length);
				// console.info(this.maxCount);
				if(arr.length >= this.maxCount){
					this.list = arr.slice(0,this.maxCount);
					this.modelCount = this.maxCount;
					this.maxSortID = this.list[this.list.length - 1].sortID;
				}else if(arr.length < this.maxCount){
					this.list = arr;
					if(arr.length > 0){
						this.modelCount = this.list.length;
						this.maxSortID = this.list[this.list.length - 1].sortID;
					}
					// 如果元素数量少于this.maxCount个则新增一个上传图片按钮
					this.list.push({
						id:0,
						sortID:10000,//按钮始终放在末尾位置，默认排序号10000
						src:'',
						isAdd: true
					})
				}
				
			},
			// 初始化处理，根据每列显示数和总行数，计算每个元素偏移
			initGrid(list = this.list) {
				let arr = []
				let x = 0;
				// let y = this.beforeHeight;
				let tmpIndex = 0;
				if (list && list.length > 0) {
					// 先计算出总行数
					this.row = Math.ceil(list.length / this.column);
					// 计算每个元素的宽高，宽高相同,这里屏幕宽度-容器内间距*2（包含左右的内间距）-元素间距（元素的数量-1即为这个间距值的数量，比如3个元素，那么只会有1和2的间距，2和3的间距）
					this.height = this.width = (this.windowWidth - this.areaXGap * 2 - (this.column - 1) * this.viewGap) / this.column;
					// 元素列表所占据的总高度（包含各种内边距，元素和元素的间距）
					this.listHeight = this.height * this.row + this.areaYGap * 2 + (this.row - 1) * this.viewGap;
					// 每行循环，设置x和y偏移
					for(var row = 1; row<= this.row; row++){
						// 取出第一行数据，根据分页算法
						let min = (row - 1) * this.column;
						let max = row * this.column;
						max = max > list.length ? list.length : max;
						let rowList = list.slice(min, max);
						// 计算偏移
						let lastx = this.areaXGap;
						let lasty = (this.beforeHeight + this.areaYGap + (row -1) * (this.height + this.viewGap));
						rowList.map((item,index)=>{
							
							if(index==0){
								x = lastx;
							}else{
								x = lastx + index * (this.width + this.viewGap);
							}
							if (item.isAdd){
								this.addObject = {
									...item,
									y: lasty,
									x,
									// 默认上传图片按钮不可移动
									direction: 'all', 
									disabled : true,
									animation: true,
									rowNumber: row,
									columnNumber: index + 1,
									width: this.width,
									height: this.height
								};
								arr.push(this.addObject)
							}else{
								arr.push({
									...item,
									y: lasty,
									x,
									// 默认上传图片按钮不可移动
									direction: 'all', 
									disabled : false,
									animation: true,
									rowNumber: row,
									columnNumber: index + 1,
									width: this.width,
									height: this.height
								})
							}
							tmpIndex++;
						});
						
					}
				}
				this.list = arr
			},
			fixResourcesUrl(url){
				// 此方法是用于修改url【某些平台下图片必须使用全路径】
				return url;
			},
			// 查找目标元素【当前鼠标X坐标和Y坐标】
			findTarget(touchX,touchY){
				// 如果当前拖拽元素不存在，直接返回
				if (this.activeModel == null) return
				// 设置标志，用于判断是否需要更新元素操作
				let isAddContain = true;
				// 循环找出，当前鼠标坐标点在哪个元素的范围内，即找出目标元素
				this.list.map((res, index) => {
					// 如果当前鼠标坐标在目标元素内则重排更新排序号
					// 需要排除掉自己和上传图片按钮
					if (res.x < touchX && touchX <= (res.x + this.width) && touchY > res.y && touchY <= (res.y + this.height) && this.activeModel.id != res.id && !res.isAdd) {
						// 此处目标元素肯定不是上传图片按钮，所以设置一下标志
						isAddContain = false;
						// 记录目标索引ID
						this.targetModel = res;
						this.isUpdate = true;
						
						// // 获取目标元素的排序号
						// let temNumber = res.sortID;
						// // 获取拖拽元素排序号
						// var activeModel = this.getModel(this.activeID);
						// let activeNumber = activeModel.sortID;
						// // 如果是小向大移动，那么在拖拽元素和当前目标元素之间的(包括目标元素)顺序都要-1
						// if (activeNumber < temNumber) {
						// 	this.list.map((_item,_index)=>{
						// 		// 这里需要改排序号的包括目标元素自己
						// 		if( activeNumber < _item.sortID && _item.sortID <= temNumber){
						// 			_item.sortID--;
						// 			// 这里不光排序号要-1，x偏移也需要自减，y偏移可能需要自减
						// 			// _item.x = _item.x  - 
						// 		}
						// 	})
						// }
						// // 如果是大向小移动，那么在当前目标元素之后(包括目标元素)和拖拽元素之间的元素顺序都需要+1
						// else if(activeNumber > temNumber){
						// 	this.list.map((_item,_index)=>{
						// 		// 这里需要改排序号的包括目标元素自己
						// 		if( temNumber <= _item.sortID && _item.sortID < activeNumber){
						// 			_item.sortID++;
						// 		}
						// 	})
						// }
						// // 改完之后，把目标元素原排序号更新到拖拽元素上
						// activeModel.sortID = temNumber;
					}
				})
				// 如果目标元素非新增按钮，则更新操作
				if(!isAddContain&&this.isUpdate){
					this.updateList();
				}
			},
			// 更新元素偏移
			updateList(){
				// console.info(this.list);
				// 把目标元素旧的偏移记录下来
				this.targetX = this.targetModel.x;
				this.targetY = this.targetModel.y;
				let targetSortID = this.targetModel.sortID;
				let rowNumber = this.targetModel.rowNumber;
				let columnNumber = this.targetModel.columnNumber;
				// 其实需要改变x.y偏移和排序号的始终是拖拽元素和目标元素之间的元素
				if(this.activeModel.sortID > targetSortID){
					// 从大到小,需要判断是同行移动，还是跨行移动
					if(this.activeModel.rowNumber == rowNumber){
						// 单行只需要改变x偏移，从后往前以此修改之间元素偏移
						for(var sortid = this.activeModel.sortID - 1;sortid >= targetSortID; sortid-- ){
							var model = this.getModelBySortID(sortid);
							model.x = model.x + (this.width + this.viewGap);
							model.sortID++;
							model.columnNumber++;
						}
					}else{
						// 如果激活元素和目标元素不在一行
						for(var sortid = this.activeModel.sortID - 1;sortid >= targetSortID; sortid-- ){
							var model = this.getModelBySortID(sortid);
							model.sortID++;
							// 此时由于不在同一行，需要改变的元素可能存在需要换行的情况，需要分别处理						
							if(model.columnNumber == this.column){
								// 如果当前元素处于最后一列，那么需要换行
								model.columnNumber = 1;
								model.rowNumber++;
								model.y = (this.beforeHeight + this.areaYGap + (model.rowNumber -1) * (this.height + this.viewGap))
								model.x = this.areaXGap + (model.columnNumber - 1) * (this.width + this.viewGap);
							}else{
								// 如果当前元素不处于临界状态，不需要考虑换行问题
								model.x = model.x + (this.width + this.viewGap);
								model.columnNumber++;
							}
						}
					}
				}else if(this.activeModel.sortID < targetSortID){
					// 从小到大，需要判断是同行移动，还是跨行移动
					if(this.activeModel.rowNumber == rowNumber){
						// 单行只需要改变x偏移，从前往后以此修改之间元素偏移
						for(var sortid = this.activeModel.sortID + 1;sortid <= targetSortID; sortid++ ){
							var model = this.getModelBySortID(sortid);
							model.x = model.x - (this.width + this.viewGap);
							model.sortID--;
							model.columnNumber--;
						}
					}else{
						// 如果激活元素和目标元素不在一行
						for(var sortid = this.activeModel.sortID + 1;sortid <= targetSortID; sortid++ ){
							var model = this.getModelBySortID(sortid);
							model.sortID--;
							// 此时由于不在同一行，需要改变的元素可能存在需要换行的情况，需要分别处理						
							if(model.columnNumber == 1){
								// 如果当前元素处于第一列，那么需要减一行
								model.columnNumber = this.column;
								model.rowNumber--;
								model.y = (this.beforeHeight + this.areaYGap + (model.rowNumber -1) * (this.height + this.viewGap))
								model.x = this.areaXGap + (model.columnNumber - 1) * (this.width + this.viewGap);
							}else{
								// 如果当前元素不处于临界状态，不需要考虑换行问题
								model.x = model.x - (this.width + this.viewGap);
								model.columnNumber--;
							}
						}
						
					}
				}
				this.activeModel.sortID = targetSortID;
				this.activeModel.columnNumber = columnNumber;
				this.activeModel.rowNumber = rowNumber;
			},
			removeItem(){
				// 大于sortID的元素都需要移动
				var activeSortID = this.activeModel.sortID;
				// 找出当前删除元素的索引
				var _index = -1;
				this.list.map((item,index)=>{
					if(item == this.activeModel){
						_index = index;
						return;
					}
				})
				// 
				if(_index>-1){
					this.list.splice(_index,1);
				}
				
				// 取出元素【排序】最后一个元素，把一些旧的数据记录起来
				// 这里不能直接用索引取！！！
				// 这里还需要判断当前删除的元素是不是排序最大的那个，如果是的话lastModel就是activeModel
				var lastModel = this.maxSortID == activeSortID? this.activeModel : this.getModelBySortID(this.maxSortID);
				// var lastX= lastModel.x;
				// var lastY= lastModel.y;
				var lastRowNumber= lastModel.rowNumber;
				var lastColumnNumber= lastModel.columnNumber;
				
				for(var i = 0; i < this.list.length; i++ ){
					var model = this.list[i];
					
					if(model.sortID > activeSortID){
						// 大于当前删除元素的排序号需要自减
						// 新增按钮不需要更改排序号
						if(!model.isAdd){
							model.sortID--;
						}
						if(model.rowNumber == 1){
							// 如果第一行y偏移不变，行数不变
							model.x = model.x - (this.width + this.viewGap);
							model.columnNumber--;
						}else{
							// 如果不是第一行情况下
							if(model.columnNumber == 1){
								// 如果当前元素处于第一列，那么需要减一行，并且列需要变成上一行最后一个元素
								model.columnNumber = this.column;
								model.rowNumber--;
								model.y = (this.beforeHeight + this.areaYGap + (model.rowNumber -1) * (this.height + this.viewGap))
								model.x = this.areaXGap + (model.columnNumber - 1) * (this.width + this.viewGap);
							}else{
								// 如果当前元素不处于临界状态，不需要考虑换行问题
								model.x = model.x - (this.width + this.viewGap);
								model.columnNumber--;
							}
						}

					}
				}
				
				// 如果此时新增按钮不存在，肯定数据元素数量为最大值，由于删除了一个元素，需要将新增按钮插入到list中
				// console.info(this.list);
				if(!this.addObject){
					// 这里不能直接使用lastY和lastX
					// 如果删除的是最后一个元素
					// lastX和lastY是该元素拖动最后位置的偏移值，所以这里需要动态计算
					this.addObject = {
						id:0,
						sortID:10000,//按钮始终放在末尾位置，默认排序号10000
						src:'',
						isAdd: true,
						// y: lastY,
						// x: lastX,
						direction: 'all', 
						disabled : true,
						animation: true,
						rowNumber: lastRowNumber,
						columnNumber: lastColumnNumber,
						width: this.width,
						height: this.height
					};
					this.addObject.x = this.areaXGap + (this.addObject.columnNumber - 1) * (this.width + this.viewGap);
					this.addObject.y = (this.beforeHeight + this.areaYGap + (this.addObject.rowNumber -1) * (this.height + this.viewGap));
					
					this.list.push(this.addObject);
					// console.info(this.list);
				}
				// console.info(this.addObject);
				// 元素列表所占据的总高度（包含各种内边距，元素和元素的间距）
				this.listHeight = this.height * this.addObject.rowNumber + this.areaYGap * 2 + (this.addObject.rowNumber - 1) * this.viewGap;
			},
			touchstart(e) {
				// 如果是新增按钮被触及不用管
				if(e.currentTarget.dataset.isadd){
					return;
				}

				var me = this;
				// 这里是因为click事件也会触发touchstart、touchmove、touchend事件
				// 所以防抖延迟处理，如果是click，那么会依次立即触发touchstart->touchmove->touchend，而在touchend中会将定时器清除
				// 如果是按住不动保持touchDebounceWait时间，此时不会触发touchend事件
				touchTimeOut = setTimeout(function(){
					me.isDrag = true;

					// 计算 x y 轴点击位置
					var query = uni.createSelectorQuery().in(me)
					query.select('#drag').boundingClientRect()
					query.select('#dragsort-delete').boundingClientRect()
					query.exec((res) => {
						// 获取删除区域信息
						me.deleteArea = res[1];
						// console.info(res);
						// 获取容器drag位置信息，TOP为距离顶部的距离，LEFT为距离左边的距离
						me.topY = res[0].top
						me.topX = res[0].left
						
						// 记录当前拖拽元素
						me.activeModel = me.getModel(Number(e.currentTarget.dataset.id));
						me.activeModel.width += 10;
						me.activeModel.height += 10;
						me.activeX = me.activeModel.x;
						me.activeY = me.activeModel.y;
						
						// 获取鼠标实时的坐标
						let temY = e.mp.touches[0].clientY - me.topY
						let temX = e.mp.touches[0].clientX - me.topX
						// 这里需要处理一下，如果直接把鼠标实时坐标复制给拖拽元素的xy偏移，那么此时元素的左上角会对准当前鼠标位置
						// 而正常情况下，我们点击的可能是元素的正中间，或者别的位置，所以需要修正一下
						// 这里x和y分别减去宽度和高度的一半，相当于把元素向左和向上偏移一半，把元素中心位置对应到鼠标点击的问题
						let itemY = temY - (me.height + 10)/2
						let itemX = temX - (me.width + 10)/2
						// 把当前坐标设置到当前拖拽元素的xy偏移值
						me.activeModel.y = itemY
						me.activeModel.x = itemX
						me.activeModel.animation = false
					})
					
				},touchDebounceWait)
				
			},
			touchmove(e) {
				// 如果是新增按钮被触及不用管
				if(e.currentTarget.dataset.isadd){
					return;
				}

				var me = this;
				if(touchMoveTimeOut) clearTimeout(touchMoveTimeOut);
				touchMoveTimeOut = setTimeout(function(){
					// 如果当前拖拽元素不存在，直接返回
					if (me.activeModel == null) return
					
					// 这里主要是为了解决touchmove触发比较频繁，而手指在操作时候，会产生小范围抖动，会造成拖动元素快速来回抖动
					// 所以这里修复如果和上次相比，移动距离小于20px则直接会返回
					if(lastTouchE){
						if(Math.abs(e.mp.touches[0].clientY - lastTouchE.mp.touches[0].clientY)<20
						&&Math.abs(e.mp.touches[0].clientX - lastTouchE.mp.touches[0].clientX)<20){
							return;
						}
					}
					lastTouchE = e;
					
					// 获取鼠标实时的坐标
					let temY = e.mp.touches[0].clientY - me.topY
					let temX = e.mp.touches[0].clientX - me.topX
					// 这里需要处理一下，如果直接把鼠标实时坐标复制给拖拽元素的xy偏移，那么此时元素的左上角会对准当前鼠标位置
					// 而正常情况下，我们点击的可能是元素的正中间，或者别的位置，所以需要修正一下
					// 这里x和y分别减去宽度和高度的一半，相当于把元素向左和向上偏移一半，把元素中心位置对应到鼠标点击的问题
					// console.info(me.activeModel);
					let itemY = temY - (me.height + 10)/2;
					let itemX = temX - (me.width + 10)/2;
					// 把当前坐标设置到当前拖拽元素的xy偏移值
					me.activeModel.y = itemY
					me.activeModel.x = itemX
					me.activeModel.animation = false
					
					// 判断是否进入删除区域
					if(temY >= me.deleteArea.top){
						// 进入删除区域，不做排序操作
						me.deleteText = '松手即可删除';
						return;
					}else{
						me.deleteText = '拖动到此处删除';
					}
					
					// touchmove触发太频繁，防抖处理，N秒后判断是否需要更改排序和偏移
					// 这里防抖函数使用util内的，延迟没有作用，还是会执行多次，暂时无法解决 不知道什么问题
					if(timeOut) clearTimeout(timeOut);
					timeOut = setTimeout(function(){
						me.findTarget(temX, temY);
					},debounceWait);
				},touchMoveDebounceWait)
			},
			touchend(e) {
				// 如果是新增按钮被触及不用管
				if(e.currentTarget.dataset.isadd){
					return;
				}
				
				if(touchTimeOut) clearTimeout(touchTimeOut);
				
				// 如果当前拖拽元素不存在，直接返回
				if (this.activeModel == null) return
				
				// 判断是否删除操作
				// 获取鼠标实时的坐标
				// console.info(e);
				let temY = e.mp.changedTouches[0].clientY - this.topY
				// let temX = e.mp.touches[0].clientX - me.topX
				// 判断是否进入删除区域
				if(temY >= this.deleteArea.top){
					// 进入删除区域，不做排序操作，直接触发删除
					this.removeItem();
					this.modelCount--;
					this.maxSortID--;
					this.$emit('delete',{model:this.activeModel, list: this.list.filter(item=>{
					return !item.isAdd;
				})});
					
				}else{
					// 将拖拽元素移动到排序号所在的位置
					this.activeModel.width -= 10;
					this.activeModel.height -= 10;
					if(this.targetModel){
						// 如果目标元素存在情况下，激活元素的偏移即为目标元素旧的偏移
						this.activeModel.x = this.targetX;
						this.activeModel.y = this.targetY;
					}else{
						// 如果目标元素不存在，还原激活元素的旧的位置
						this.activeModel.x = this.activeX;
						this.activeModel.y = this.activeY;
					}
					this.activeModel.animation = true;
					// 如果确实更新了数据，那么触发事件
					if(this.isUpdate){
						this.isUpdate = false;
						this.$emit('sort',this.list.filter(item=>{ return !item.isAdd;}));
					}
				}
				
				// 重置数据
				this.activeModel = null;
				this.targetModel = null;
				this.isDrag = false;
				this.deleteArea = null;
				this.deleteText = '拖动到此处删除';
				lastTouchE = null;
				
			},
			getModel(pk_id){
				// 根据主键key查找元素
				if(this.list && this.list.length > 0){
					for(var i = 0; i< this.list.length; i++){
						if(this.list[i].id == pk_id){
							return this.list[i];
						}
					}
				}
				return null;
			},
			getModelBySortID(sortID){
				// 根据主键key查找元素
				if(this.list && this.list.length > 0){
					for(var i = 0; i< this.list.length; i++){
						if(this.list[i].sortID == sortID){
							return this.list[i];
						}
					}
				}
				return null;
			},
			onClick(model,index,list) {
				this.$emit('click',{model,index,list:list.filter(item=>{
					return !item.isAdd;
				})});
			},
			onAdd() {
				const self = this;
				uni.chooseImage({
					count: 9 - self.modelCount, // 默认9
					sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
					sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有
					success: (res) => {
						if(res.tempFilePaths){
							res.tempFilePaths.map((item,index)=>{
								// 延迟触发一下
								setTimeout(function(){
										self.maxSortID++;
										let src = item;
										self.$emit('add',{src, sortID: self.maxSortID});
									},200);
							})
						}
					}
				});
			},
			// 供外部调用，新增一个元素
			add(item){
				// console.info(item);
				// 如果没有新增按钮，则不新增
				if(!this.addObject){
					return;
				}
				this.modelCount++;
				
				// 有新增按钮情况下，包括新增按钮，元素长度是否为maxCount
				// 是的话，新增按钮需要移除
				if(this.list.length == this.maxCount){
					
					var model = Object.assign({},item,this.addObject);
					model.isAdd = false;
					model.disabled = false;
					model.src = item.src;
					model.id = item.id;
					model.sortID = item.sortID;
					
					this.list.splice(this.maxCount-1,1,model);
					this.addObject = null;
				}else{
					var model = Object.assign({},item,this.addObject);
					model.isAdd = false;
					model.disabled = false;
					model.src = item.src;
					model.id = item.id;
					model.sortID = item.sortID;
					
					this.list.splice(this.list.length-1,0,model);
					// 新增按钮可能存在需要换行的情况，需要分别处理
					if(this.addObject.columnNumber == this.column){
						// 如果处于最后一列，那么需要换行
						this.addObject.columnNumber = 1;
						this.addObject.rowNumber++;
						this.addObject.y = (this.beforeHeight + this.areaYGap + (this.addObject.rowNumber -1) * (this.height + this.viewGap))
						this.addObject.x = this.areaXGap + (this.addObject.columnNumber - 1) * (this.width + this.viewGap);
						// 元素列表所占据的总高度（包含各种内边距，元素和元素的间距）
						this.listHeight = this.height * this.addObject.rowNumber + this.areaYGap * 2 + (this.addObject.rowNumber - 1) * this.viewGap;
					}else{
						// 如果不处于临界状态，不需要考虑换行问题
						this.addObject.x = this.addObject.x + (this.width + this.viewGap);
						this.addObject.columnNumber++;
					}
				}
				
				
			}
		}
	}
</script>

<style scoped>
	/* 页面布局样式BEGIN */
	.dragsort-box {
		width: 100%;
		height: 100%;
		overflow: hidden;
	}

	.dragsort-area {
		width: 100%;
		height: 100%;
		/* width: calc(100% - 60rpx);
	height: calc(100% - 40rpx);
	padding: 20rpx 30rpx; */
	}

	.dragsort-before {}

	/* 需要撑开拖拽内容区域高度 */
	.dragsort-list {}

	.dragsort-after {}

	.dragsort-delete {
		position: fixed;
		bottom: 0;
		left: 0;
		z-index: 100;
		width: 100%;
		/* padding: 14rpx 0; */
		height: 90rpx;
		background-color: #dd6161;
		color: #FFFFFF;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: space-around;
		opacity: 0;
	}
	.opacity{
		opacity: 1;
	}
	
	.deleteicon {
		font-size: 17px;
	}

	.dragsort-view {
		position: absolute !important;
		display: flex;
		/* height: 80px; */
		align-items: center;
		/* width: 20%; */
		text-align: center;
		/* background-color: #C0C4CC; */
		color: #fff;
		/* border-radius: 5px; */
		box-sizing: border-box;
		z-index: 90;
	}

	.dragsort-view-active {
		/* box-shadow: 0 0 40rpx #DDDDDD; */
		z-index: 99;
	}

	.dragsort-view-item {
		position: relative;
		flex: 1;
		font-size: 16px;
		width: 100%;
		height: 100%;
	}
	.dragsort-view-item-image{
		/* width: 100%; */
	}
	
	.btnAdd{
		background-color: #F7F7F7;
		height: 100%;
		width: 100%;
		display: flex;
		flex-direction: row;
		justify-content: center;
		align-items: center;
	}
	.btnAdd-icon{
		color: #B2B2B2;
		font-size: 90rpx;
	}
	/* 页面布局样式END */

</style>
